"""
交易成本计算模块
包含手续费和资金费用计算
"""
from typing import Dict, Optional
from datetime import datetime, timedelta
from src.utils.logger import get_logger

logger = get_logger(__name__)


class CostCalculator:
    """交易成本计算器"""

    def __init__(self, maker_fee: float = 0.02, taker_fee: float = 0.05,
                 funding_rate: float = 0.03):
        """
        初始化

        Args:
            maker_fee: Maker手续费 (%)
            taker_fee: Taker手续费 (%)
            funding_rate: 资金费率 (%) - 永续合约每8小时结算一次
        """
        self.maker_fee = maker_fee / 100
        self.taker_fee = taker_fee / 100
        self.funding_rate = funding_rate / 100

    def calculate_trading_fee(self, quantity: float, price: float,
                            is_maker: bool = False) -> float:
        """
        计算交易手续费

        Args:
            quantity: 交易数量
            price: 价格
            is_maker: 是否为Maker单

        Returns:
            手续费 (USDT)
        """
        trade_value = quantity * price
        fee_rate = self.maker_fee if is_maker else self.taker_fee
        fee = trade_value * fee_rate

        return fee

    def calculate_funding_fee(self, quantity: float, avg_price: float,
                            holding_hours: float, funding_rate: Optional[float] = None) -> float:
        """
        计算永续合约资金费

        OKX资金费结算规则:
        - 每8小时结算一次 (0:00, 8:00, 16:00 UTC)
        - 多头支付资金费 > 0, 空头收取资金费 < 0

        Args:
            quantity: 持仓数量
            avg_price: 平均开仓价格
            holding_hours: 持仓时长 (小时)
            funding_rate: 资金费率 (%) - 如果为None则使用默认值

        Returns:
            资金费用 (USDT)
        """
        if funding_rate is None:
            funding_rate = self.funding_rate
        else:
            funding_rate = funding_rate / 100

        # 资金费按持仓时长计算 (每8小时一个周期)
        funding_periods = holding_hours / 8

        position_value = quantity * avg_price
        total_funding_fee = position_value * funding_rate * funding_periods

        return total_funding_fee

    def calculate_total_costs(self, trade_info: Dict) -> Dict:
        """
        计算单笔交易的总成本

        Args:
            trade_info: 交易信息字典
                {
                    'entry_quantity': float,      # 入场数量
                    'entry_price': float,         # 入场价格
                    'exit_quantity': float,       # 出场数量
                    'exit_price': float,          # 出场价格
                    'holding_hours': float,       # 持仓时长
                    'trade_type': str,            # 'spot' or 'perpetual'
                    'is_long': bool,              # 是否多头
                }

        Returns:
            成本明细字典
        """
        entry_qty = trade_info['entry_quantity']
        entry_price = trade_info['entry_price']
        exit_qty = trade_info['exit_quantity']
        exit_price = trade_info['exit_price']
        holding_hours = trade_info['holding_hours']
        trade_type = trade_info.get('trade_type', 'spot')

        # 入场手续费 (假设为Taker)
        entry_fee = self.calculate_trading_fee(entry_qty, entry_price, is_maker=False)

        # 出场手续费 (假设为Taker)
        exit_fee = self.calculate_trading_fee(exit_qty, exit_price, is_maker=False)

        # 资金费 (仅永续合约)
        funding_fee = 0.0
        if trade_type == 'perpetual':
            funding_fee = self.calculate_funding_fee(entry_qty, entry_price, holding_hours)

        # 总成本
        total_cost = entry_fee + exit_fee + abs(funding_fee)

        return {
            'entry_fee': entry_fee,
            'exit_fee': exit_fee,
            'funding_fee': funding_fee,
            'total_cost': total_cost,
            'cost_rate': (total_cost / (entry_qty * entry_price)) * 100,  # 成本率(%)
        }

    def calculate_breakeven_price(self, entry_price: float, entry_qty: float,
                                 exit_qty: float, trade_type: str = 'spot') -> float:
        """
        计算盈亏平衡点 (考虑手续费)

        Args:
            entry_price: 入场价格
            entry_qty: 入场数量
            exit_qty: 出场数量
            trade_type: 交易类型

        Returns:
            盈亏平衡价格
        """
        entry_value = entry_qty * entry_price

        # 入场手续费
        entry_fee = self.calculate_trading_fee(entry_qty, entry_price, is_maker=False)

        # 出场手续费 (基于出场价格估算)
        exit_fee_rate = self.taker_fee
        exit_fee_value = exit_qty * exit_fee_rate

        # 总费用
        total_fees = entry_fee + exit_fee_value

        # 盈亏平衡点 = (入场总值 + 总费用) / 出场数量
        breakeven_price = (entry_value + total_fees) / exit_qty

        return breakeven_price

    def calculate_profit_loss(self, entry_price: float, exit_price: float,
                             quantity: float, trade_type: str = 'spot',
                             holding_hours: float = 0) -> Dict:
        """
        计算净盈亏 (扣除所有费用)

        Args:
            entry_price: 入场价格
            exit_price: 出场价格
            quantity: 交易数量
            trade_type: 交易类型
            holding_hours: 持仓时长 (永续合约需要)

        Returns:
            盈亏详情字典
        """
        # 毛盈亏
        gross_pnl = (exit_price - entry_price) * quantity
        pnl_pct = ((exit_price - entry_price) / entry_price) * 100

        # 交易费
        entry_fee = self.calculate_trading_fee(quantity, entry_price, is_maker=False)
        exit_fee = self.calculate_trading_fee(quantity, exit_price, is_maker=False)
        trading_fee = entry_fee + exit_fee

        # 资金费
        funding_fee = 0.0
        if trade_type == 'perpetual':
            funding_fee = self.calculate_funding_fee(quantity, entry_price, holding_hours)

        # 净盈亏
        net_pnl = gross_pnl - trading_fee - abs(funding_fee)
        net_pnl_pct = (net_pnl / (entry_price * quantity)) * 100

        return {
            'gross_pnl': gross_pnl,
            'gross_pnl_pct': pnl_pct,
            'entry_fee': entry_fee,
            'exit_fee': exit_fee,
            'trading_fee': trading_fee,
            'funding_fee': funding_fee,
            'net_pnl': net_pnl,
            'net_pnl_pct': net_pnl_pct,
        }
